#ifndef __MAKE_ENUM__
#define __MAKE_ENUM__

#include <sstream>
#include <string>
#include <vector>

#define MAKE_ENUM(name, ...)                              \
    enum name { __VA_ARGS__, name##__COUNT };             \
    std::string name##ToStr(name value) {                 \
        std::string              enumName = #name;        \
        std::string              str      = #__VA_ARGS__; \
        int                      len      = str.length(); \
        std::vector<std::string> strings;                 \
        std::ostringstream       temp;                    \
        for (int i = 0; i < len; i++) {                   \
            if (isspace(str[i]))                          \
                continue;                                 \
            else if (str[i] == ',') {                     \
                strings.emplace_back(temp.str());         \
                temp.str(std::string());                  \
            }                                             \
            else                                          \
                temp << str[i];                           \
        }                                                 \
        strings.emplace_back(temp.str());                 \
        return strings[value];                            \
    }

#define MAKE_ENUM_CLASS(name, ...)                        \
    enum class name { __VA_ARGS__, name##__COUNT };       \
    std::string name##ToStr(name value) {                 \
        std::string              enumName = #name;        \
        std::string              str      = #__VA_ARGS__; \
        int                      len      = str.length(); \
        std::vector<std::string> strings;                 \
        std::ostringstream       temp;                    \
        for (int i = 0; i < len; i++) {                   \
            if (isspace(str[i]))                          \
                continue;                                 \
            else if (str[i] == ',') {                     \
                strings.emplace_back(temp.str());         \
                temp.str(std::string());                  \
            }                                             \
            else                                          \
                temp << str[i];                           \
        }                                                 \
        strings.emplace_back(temp.str());                 \
        return strings[static_cast<int>(value)];          \
    }

#endif // __MAKE_ENUM__